﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IPC.Communication.Framework.Profinet.Keyence
{
    internal class KeyenceSR2000Helper
    {
        public static OperateResult<string> ReadBarcode(Func<byte[], OperateResult<byte[]>> readCore)
        {
            OperateResult<string> operateResult = ReadCustomer("LON", readCore);
            if (!operateResult.IsSuccess && operateResult.ErrorCode < 0)
            {
                ReadCustomer("LOFF", readCore);
            }
            return operateResult;
        }

        public static OperateResult Reset(Func<byte[], OperateResult<byte[]>> readCore)
        {
            return ReadCustomer("RESET", readCore);
        }

        public static OperateResult OpenIndicator(Func<byte[], OperateResult<byte[]>> readCore)
        {
            return ReadCustomer("AMON", readCore);
        }

        public static OperateResult CloseIndicator(Func<byte[], OperateResult<byte[]>> readCore)
        {
            return ReadCustomer("AMOFF", readCore);
        }

        public static OperateResult<string> ReadVersion(Func<byte[], OperateResult<byte[]>> readCore)
        {
            return ReadCustomer("KEYENCE", readCore);
        }

        public static OperateResult<string> ReadCommandState(Func<byte[], OperateResult<byte[]>> readCore)
        {
            return ReadCustomer("CMDSTAT", readCore);
        }

        public static OperateResult<string> ReadErrorState(Func<byte[], OperateResult<byte[]>> readCore)
        {
            return ReadCustomer("ERRSTAT", readCore);
        }

        public static OperateResult<bool> CheckInput(int number, Func<byte[], OperateResult<byte[]>> readCore)
        {
            OperateResult<string> operateResult = ReadCustomer("INCHK," + number.ToString(), readCore);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool>(operateResult);
            }
            if (operateResult.Content == "ON")
            {
                return OperateResult.CreateSuccessResult(value: true);
            }
            if (operateResult.Content == "OFF")
            {
                return OperateResult.CreateSuccessResult(value: false);
            }
            return new OperateResult<bool>(operateResult.Content);
        }

        public static OperateResult SetOutput(int number, bool value, Func<byte[], OperateResult<byte[]>> readCore)
        {
            return ReadCustomer((value ? "OUTON," : "OUTOFF,") + number.ToString(), readCore);
        }

        public static OperateResult<int[]> ReadRecord(Func<byte[], OperateResult<byte[]>> readCore)
        {
            OperateResult<string> operateResult = ReadCustomer("NUM", readCore);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<int[]>(operateResult);
            }
            return OperateResult.CreateSuccessResult((from n in operateResult.Content.Split(',')
                                                      select int.Parse(n)).ToArray());
        }

        public static OperateResult Lock(Func<byte[], OperateResult<byte[]>> readCore)
        {
            return ReadCustomer("LOCK", readCore);
        }

        public static OperateResult UnLock(Func<byte[], OperateResult<byte[]>> readCore)
        {
            return ReadCustomer("UNLOCK", readCore);
        }

        public static OperateResult<string> ReadCustomer(string command, Func<byte[], OperateResult<byte[]>> readCore)
        {
            byte[] bytes = Encoding.ASCII.GetBytes(command + "\r");
            string text = command;
            if (command.IndexOf(',') > 0)
            {
                text = command.Substring(0, command.IndexOf(','));
            }
            OperateResult<byte[]> operateResult = readCore(bytes);
            if (!operateResult.IsSuccess)
            {
                return operateResult.Convert<string>(null);
            }
            string text2 = Encoding.ASCII.GetString(operateResult.Content).Trim('\r');
            if (text2.StartsWith("ER," + text + ","))
            {
                return new OperateResult<string>(GetErrorDescription(text2.Substring(4 + text.Length)));
            }
            if (text2.StartsWith("OK," + text) && text2.Length > 4 + text.Length)
            {
                return OperateResult.CreateSuccessResult(text2.Substring(4 + text.Length));
            }
            return OperateResult.CreateSuccessResult(text2);
        }

        public static string GetErrorDescription(string error)
        {
            switch (error)
            {
                case "00":
                    return StringResources.Language.KeyenceSR2000Error00;
                case "01":
                    return StringResources.Language.KeyenceSR2000Error01;
                case "02":
                    return StringResources.Language.KeyenceSR2000Error02;
                case "03":
                    return StringResources.Language.KeyenceSR2000Error03;
                case "04":
                    return StringResources.Language.KeyenceSR2000Error04;
                case "05":
                    return StringResources.Language.KeyenceSR2000Error05;
                case "10":
                    return StringResources.Language.KeyenceSR2000Error10;
                case "11":
                    return StringResources.Language.KeyenceSR2000Error11;
                case "12":
                    return StringResources.Language.KeyenceSR2000Error12;
                case "13":
                    return StringResources.Language.KeyenceSR2000Error13;
                case "14":
                    return StringResources.Language.KeyenceSR2000Error14;
                case "20":
                    return StringResources.Language.KeyenceSR2000Error20;
                case "21":
                    return StringResources.Language.KeyenceSR2000Error21;
                case "22":
                    return StringResources.Language.KeyenceSR2000Error22;
                case "23":
                    return StringResources.Language.KeyenceSR2000Error23;
                case "99":
                    return StringResources.Language.KeyenceSR2000Error99;
                default:
                    return StringResources.Language.UnknownError + " :" + error;
            }
        }
    }
}